import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Scanner;
import java.util.Vector;
import java.util.concurrent.LinkedBlockingQueue;
 
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
 
public class PaintGUI extends JFrame implements ActionListener, MouseListener, MouseMotionListener, ChangeListener {
    private static final long serialVersionUID = 1L; 
    private JPanel colorPanel, chatPanel, inputPanel, mainColorPanel;   
    private JButton red, yellow, green, blue, purple, black, cyan, orange, pink, send_button, white, size_col, connect_to_user; 
    private JTextArea chatArea, userArea;
    private JTextField inputMessage, username;
    private JMenuBar menu;
    private JTabbedPane tabbedPane;
    private JMenu options, edit, pen_size, change_draw;
    private JMenuItem save, new_pic , load, getNewContacts, SendAFile, radi1, radi5, radi10, radi15, drawLine, drawCircle, normal, airbrush, eraser, create_tab_for_painting, delete_tab;
    private PaintCanvas canvas, newCanvas, cur_canvas;
    private boolean ConnectionIsOpen;
    Boolean destinationSocketReadyForBody;
    private int curTab = 0;
    private LinkedBlockingQueue<DrawingChange> drawingQueue;
    private LinkedBlockingQueue<String> chatQueue;
    private JScrollPane scrollPane;
    private JList userList;
    private JPanel userPanel;
        
    String SavingDirectory = System.getProperty("user.dir");
    String ThisComputerHostName;
    
    Vector<String> ListOfHosts;
    Vector<String> UniqueTabNames;
    Vector<String> onlineUsers;
    Vector<HostNameAndPortNumber> NamesAndPorts;
    Vector<PointDrawn> PointsToBeSent;
 
    PaintGUI PassingInActionListener;
    Receiver receiver;
    String chatUpdate;
    DrawingChange drawingUpdate;
    UpdateLoop updateLoop;
 
public PaintGUI() throws FileNotFoundException{
       
       
        drawingQueue = new LinkedBlockingQueue<DrawingChange>();
        chatQueue = new LinkedBlockingQueue<String>();
       
        UniqueTabNames = new Vector<String>();
       
    PassingInActionListener = this;
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    setLocation(200,100);
    setSize(1000, 700);
    setTitle("Interactive Paint");
    setLayout(new BorderLayout()); 
    createCanvas();
    createColorButtons();
    createInputMessage();
    createChatArea();
    createMenu();
 
    PointsToBeSent = new Vector<PointDrawn>();
    NamesAndPorts = new Vector<HostNameAndPortNumber>();
 
 
 
        InetAddress addr;
        try {
            addr = InetAddress.getLocalHost();
            ThisComputerHostName = addr.getHostName();
            
            ListOfHosts = new Vector<String>();
            onlineUsers = new Vector<String>();
                String[] ListOfHostsArray = {"merry", "pippin", "sam", "gimli", "aragorn", "boromir", "legolas", "bill", "shadowfax", "bilbo", "gollum", "eowyn"};
                for(int j = 0; j < ListOfHostsArray.length; j++) {
                        ListOfHosts.add(ListOfHostsArray[j]);
                        onlineUsers.add(ListOfHostsArray[j]);
                }
        } catch (UnknownHostException e2) {

                e2.printStackTrace();
        }
    try {
        receiver = new Receiver(8888, chatArea, this, drawingQueue, chatQueue);
        receiver.start();
        } catch (IOException e) {
                e.printStackTrace();
        }
        updateLoop = new UpdateLoop(chatArea, scrollPane, drawingQueue, chatQueue, this);
        updateLoop.start();
        createUserPanel();
}

public void createUserPanel(){
        userPanel = new JPanel(new BorderLayout());
        connect_to_user = new JButton("Connect");       
        userPanel.add(connect_to_user, BorderLayout.NORTH);
        userList= new JList(onlineUsers);         
        userPanel.add(userList, BorderLayout.CENTER);        
        add(userPanel, BorderLayout.EAST);
        connect_to_user.addActionListener(this);
}
 
public void createCanvas(){
            tabbedPane = new JTabbedPane();
            canvas = new PaintCanvas(this);
            //We've also got to have a method here that gets the current connections
            //as well as the other user's tabs
            //getConnectedUsersTabs();
            canvas.addMouseListener(this);
            canvas.addMouseMotionListener(this);
            add(tabbedPane, BorderLayout.CENTER);
            tabbedPane.addChangeListener(this);           
}
 
public void createColorButtons(){ 
    size_col = new JButton("5"); size_col.setBackground(Color.black);      
    black = new JButton();black.setBackground(Color.black);
    red = new JButton();red.setBackground(Color.red);
    yellow = new JButton();yellow.setBackground(Color.yellow);
    green = new JButton();green.setBackground(Color.green);
    blue = new JButton();blue.setBackground(Color.blue);
    purple = new JButton();purple.setBackground(Color.magenta); 
    cyan = new JButton();cyan.setBackground(Color.cyan);
    orange = new JButton();orange.setBackground(Color.orange);
    pink = new JButton();pink.setBackground(Color.PINK);
    white = new JButton(); white.setBackground(Color.white);
    colorPanel = new JPanel(new GridLayout(0,2));
    mainColorPanel = new JPanel(new BorderLayout());
    colorPanel.add(black);
    colorPanel.add(red);
    colorPanel.add(yellow);
    colorPanel.add(green);
    colorPanel.add(blue);
    colorPanel.add(purple);
    colorPanel.add(cyan);
    colorPanel.add(orange);
    colorPanel.add(pink);
    colorPanel.add(white);  
    mainColorPanel.add(colorPanel);
    mainColorPanel.add(size_col, BorderLayout.SOUTH);
    add(mainColorPanel, BorderLayout.WEST);
    red.addActionListener(this); black.addActionListener(this);yellow.addActionListener(this);blue.addActionListener(this);purple.addActionListener(this);orange.addActionListener(this);
    pink.addActionListener(this); cyan.addActionListener(this); green.addActionListener(this);white.addActionListener(this);
} 
 
public void createChatArea(){
        chatPanel = new JPanel(new BorderLayout());
        chatArea = new JTextArea();
        chatArea.setText("");
        chatArea.setEditable(false);   
        chatArea.setRows(10);
        scrollPane = new JScrollPane(chatArea);
        chatPanel.add(scrollPane, BorderLayout.SOUTH);
        chatPanel.add(inputPanel, BorderLayout.NORTH);
        add(chatPanel, BorderLayout.SOUTH);
}
 
public void createInputMessage(){
        inputPanel = new JPanel(new BorderLayout());
        username = new JTextField();
        inputMessage = new JTextField();
        send_button = new JButton("Send");
        String s = JOptionPane.showInputDialog("Type in a username please");
        s += ":";
        username.setText(s);
        username.setEditable(false);
        username.setBorder(BorderFactory.createLineBorder(Color.black));
        inputMessage.setText("");
        inputMessage.setEditable(true);
        inputMessage.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        inputPanel.add(username, BorderLayout.WEST);
        inputPanel.add(inputMessage);
        inputPanel.add(send_button, BorderLayout.EAST);
        send_button.addActionListener(this);
        inputMessage.addKeyListener(new KeyListener(){         
           @Override
       public void keyPressed(KeyEvent e){
           if(e.getKeyCode() == KeyEvent.VK_ENTER){
                chatArea.append(username.getText());
                chatArea.append(" ");
                String textFromInput = inputMessage.getText();         
                chatArea.append(textFromInput);
                chatArea.append("\n");
                scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
                appendToOtherComputers(textFromInput);
                inputMessage.setText("");
           }
       }
           @Override
       public void keyReleased(KeyEvent e){
 
       }
           @Override
       public void keyTyped(KeyEvent e){
 
       }
   });
}
public void createMenu(){
         menu = new JMenuBar();
         options = new JMenu("Options");        
         pen_size = new JMenu("Stylus Size");
         change_draw = new JMenu("Draw Style");
         normal = new JMenuItem("Normal");
         eraser = new JMenuItem("Eraser");
         airbrush = new JMenuItem("Airbrush");
         create_tab_for_painting = new JMenuItem("Create New Project");
         delete_tab = new JMenuItem("Delete Current Tab");
         save = new JMenuItem("Save Project");
         load = new JMenuItem("Load Project");
         getNewContacts = new JMenuItem("Connect");
         SendAFile = new JMenuItem("Send File To Connect Users");
         radi1 = new JMenuItem("Pen Size 1");
         radi5 = new JMenuItem("Pen Size 5");
         radi10 = new JMenuItem("Pen Size 10");
         radi15 = new JMenuItem("Pen Size 15");      
         options.add(create_tab_for_painting);
         options.add(save);
         options.add(load);
         options.add(getNewContacts);
         options.add(SendAFile);
         options.add(delete_tab);

         pen_size.add(radi1);
         pen_size.add(radi5);
         pen_size.add(radi10);
         pen_size.add(radi15);
         pen_size.add(eraser);        
         change_draw.add(normal);
         change_draw.add(airbrush);
         radi1.addActionListener(this);
         radi5.addActionListener(this);
         radi10.addActionListener(this);
         radi15.addActionListener(this);
         eraser.addActionListener(this);        
         normal.addActionListener(this);
         airbrush.addActionListener(this);
         save.addActionListener(this);
         load.addActionListener(this);
         create_tab_for_painting.addActionListener(this);
         delete_tab.addActionListener(this);

         getNewContacts.addActionListener(new ActionListener() {
           @Override
                public void actionPerformed(ActionEvent arg0) {
                        System.out.println("At action listener");
                        new newUsersJFrame(PassingInActionListener).setVisible(true);
                }
         });
         SendAFile.addActionListener(
        		 
        new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    //sendAPicture();
                 Vector<String> PictureExtensions = new Vector<String>();
                 Vector<String> TextFileExtensions = new Vector<String>();
                 
                 PictureExtensions.add("jpg");
                 PictureExtensions.add("jpeg");
                 PictureExtensions.add("png");
                 PictureExtensions.add("bmp");
                 PictureExtensions.add("gif");
                 
                 TextFileExtensions.add("txt");
                 
                 File file = getAFile();
                 String fileName = file.toString();
                 String[] array = fileName.split("/");
                 while(array[array.length-1].length() < 1 && array.length > 0) {
                         String[] temp = new String[array.length-2];
                         for(int i = 0; i < array.length; i++) temp[i] = array[i];
                         array = temp;
                 }
                 for(int i = 0; i < array.length; i++) {
                         System.out.println("first  " + array[i]);
                 }
                 System.out.println("last  " + array[array.length-1]);
                 array = array[array.length-1].split("\\.");
                
                 System.out.println("array2.length " + array.length  + "two is " + array[array.length-1]);
                 
                 String FileEnding = array[array.length-1];
                 Boolean RecognizedFile = false;
                 for(int i = 0; i < PictureExtensions.size(); i++) {
                         if(PictureExtensions.get(i).equalsIgnoreCase(FileEnding)){
                             RecognizedFile = true;    
                                 sendAPictureFile(file);
                         }
                 }
                 for(int i = 0; i < TextFileExtensions.size(); i++) {
                         if(TextFileExtensions.get(i).equalsIgnoreCase(FileEnding)){
                             RecognizedFile = true;    
                                 sendATextFile(file);
                         }
                 }
                 if (!RecognizedFile){
                         JOptionPane.showMessageDialog(null, "The type of file that you selected can not be sent \n try a jpg jpeg or txt file.");
                 }
                }
         }
        		 
         );
         menu.add(options);        
         menu.add(pen_size);
         menu.add(change_draw);
         add(menu, BorderLayout.NORTH);        
}
 
public void receivedHeader(int FromPort, InetAddress FromHostName) {
         HeaderSocket weGotTheHeader = new HeaderSocket(FromHostName.getHostAddress(), 8888, 10, 0, 0);
         weGotTheHeader.start();
         System.out.println("Reply sent from this computer");
}
 
public File getAFile() {
        JFileChooser fileChooser = new JFileChooser(SavingDirectory);
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    fileChooser.showOpenDialog(null);
    File file = fileChooser.getSelectedFile();
    if(file != null) {
         System.out.println(file.toString());
         return file;
    }
    return null;
}

public void sendAPictureFile(File f) {
        try {
                BufferedImage img = ImageIO.read(f);
                for(int i = 0; i < NamesAndPorts.size(); i++) {
                         new SocketThreadForPictureTransfer(NamesAndPorts.get(i).HostName, NamesAndPorts.get(i).PortNumber, img).run();
            }
        } catch (IOException e) {
                e.printStackTrace();
        }
}
 
 
public void sendATextFile(File f) {
        BufferedReader reader;
        try {
                reader = new BufferedReader(new FileReader(f));
                Vector<String> Text = new Vector<String>();
                try {
                        while(!reader.ready()) {}
                        Text.add(reader.readLine());
                        System.out.println("Text on the sending side is  " + Text.get(Text.size()-1));
                        for(int i = 0; i < NamesAndPorts.size(); i++) {
                            new SocketThreadForTextFileTransfer(NamesAndPorts.get(i).HostName, NamesAndPorts.get(i).PortNumber, Text).start();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                };
               
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        }
}
 
public void SaveTextFileReceived(Vector<String> FileContents) {
        int response = JOptionPane.showConfirmDialog(this, "Received file called" + "on your file system, do you want to save?");
        if (response == JOptionPane.YES_OPTION) {
                System.out.println("Ok saving");
                try {
                        BufferedWriter writer = new BufferedWriter(new FileWriter("new.txt"));
                        for(int line = 0; line < FileContents.size(); line++) {
                                writer.write(FileContents.get(line));
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
        } else {
                System.out.println("Not saving");
        }
}

public void savePicture(BufferedImage img) {
        String filename = JOptionPane.showInputDialog("What should the file be called?");
        if(filename != null) {
                try {
                File outputfile = new File(SavingDirectory + "/" + filename + ".png");
                ImageIO.write(img, "png", outputfile);
            } catch (IOException e) {
                System.out.println("new image was not saved");
            }
        }
}

public void showPictureInNewFrame(BufferedImage img) {
    JFrame frame2 = new JFrame();
    JPanelForPicture panel = new JPanelForPicture(img);
    frame2.setSize(700, 700);
    frame2.add(panel);
    frame2.setVisible(true);
    panel.repaint();
    frame2.repaint();
}

public void saveAndDisplayImage(BufferedImage img ) {
        int show = JOptionPane.showConfirmDialog(null, "Display picture");
        if (show == JOptionPane.YES_OPTION) {
                showPictureInNewFrame(img);
        }
        int save = JOptionPane.showConfirmDialog(null, "Save picture");
        if(save == JOptionPane.YES_OPTION) {
                savePicture(img);
        }
}

public BufferedImage loadImage(File file) {
    BufferedImage img = null;
    try {
         img = ImageIO.read(file);
    } catch (IOException e1) {
           e1.printStackTrace();
    }
    int TotalPixels = img.getHeight()*img.getWidth();
    int[] ColorsOfImage = new int[TotalPixels];
    for(int p= 0; p < TotalPixels; p++) {
         ColorsOfImage[p] = img.getRGB(p%img.getWidth(), p/img.getWidth());
    }
    return img;
}

public void sendAPicture() {
            JFileChooser fileChooser = new JFileChooser(SavingDirectory);
            fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int returnVal = fileChooser.showOpenDialog(null);
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fileChooser.getSelectedFile(); 
                BufferedImage img = loadImage(file);
                 for(HostNameAndPortNumber HostandPort : NamesAndPorts) {
                         new SocketThreadForPictureTransfer(HostandPort.getHostName(), HostandPort.getPortNumber(), img).run();
                 }
            } else {
                 System.out.println("   No picture selected   ");
            }
}
 
public void appendToOtherComputers(String textFromInput) {     
         for(int i = 0; i < NamesAndPorts.size(); i++) {               
                new SocketThreadForChat(textFromInput, NamesAndPorts.get(i).HostName, NamesAndPorts.get(i).PortNumber, username.getText()).start();           
        }       
}
 
public void possiblyAddHost(String newHost) {
	Boolean AlreadyConnected = false;
    for(int i = 0; i < NamesAndPorts.size(); i++) {
          if ( newHost.equalsIgnoreCase(NamesAndPorts.get(i).getHostName()) ) {
        	  System.out.println("That host is already in the directory");
        	  AlreadyConnected = true;
        	  break;
          }
    }
    if(!AlreadyConnected) {
    	NamesAndPorts.add( new HostNameAndPortNumber(newHost, 8888) );
    	if(NamesAndPorts.size() == 1) getAllDrawings();
    }
    
}

@Override
public void actionPerformed(ActionEvent evt) { 
    if(evt.getSource() == send_button){
        chatArea.append(username.getText());
        chatArea.append(" ");
        String textFromInput = inputMessage.getText();
        chatArea.append(textFromInput);
        chatArea.append("\n");
        scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
        appendToOtherComputers(textFromInput);
        inputMessage.setText("");
    }
    if(evt.getSource() == red){cur_canvas.setColor(Color.red); size_col.setBackground(Color.red);} 
    if(evt.getSource() == black){cur_canvas.setColor(Color.black);size_col.setBackground(Color.black);} 
    if(evt.getSource() == yellow){cur_canvas.setColor(Color.yellow);size_col.setBackground(Color.yellow);}   
    if(evt.getSource() == green){cur_canvas.setColor(Color.green);size_col.setBackground(Color.green);} 
    if(evt.getSource() == blue){cur_canvas.setColor(Color.blue);size_col.setBackground(Color.blue);}   
    if(evt.getSource() == purple){cur_canvas.setColor(Color.magenta);size_col.setBackground(Color.magenta);}
    if(evt.getSource() == cyan){cur_canvas.setColor(Color.cyan);size_col.setBackground(Color.cyan);}
    if(evt.getSource() == orange){cur_canvas.setColor(Color.orange);size_col.setBackground(Color.orange);}
    if(evt.getSource() == pink){cur_canvas.setColor(Color.PINK);size_col.setBackground(Color.pink);}
    if(evt.getSource() == white){cur_canvas.setColor(Color.WHITE);size_col.setBackground(Color.white);} 
    if(evt.getSource() == radi1){cur_canvas.setRadius(1); size_col.setText("1");}
    if(evt.getSource() == radi5){cur_canvas.setRadius(5); size_col.setText("5");}
    if(evt.getSource() == radi10){cur_canvas.setRadius(10);size_col.setText("10");}
    if(evt.getSource() == radi15){cur_canvas.setRadius(15);size_col.setText("15");}
    if(evt.getSource() == eraser){cur_canvas.setRadius(40); cur_canvas.setColor(Color.white);size_col.setText("40");size_col.setBackground(Color.white);} 
    if(evt.getSource() == normal){cur_canvas.setDrawType(true);}
    if(evt.getSource() == airbrush){cur_canvas.setDrawType(false);}
    if(evt.getSource() == create_tab_for_painting){
         addNewTabForPainting();
         printUniqueNames();
    }
    if(evt.getSource() == delete_tab) {
         if(UniqueTabNames.size() <= 1){}
         else{
                 int CurrentPlace = tabbedPane.getSelectedIndex();
                 tabbedPane.remove(CurrentPlace);
                 UniqueTabNames.remove(CurrentPlace);
         }
    }
    if(evt.getSource() == save){try {
                cur_canvas.saveFile();
        } catch (IOException e) {
                e.printStackTrace();
        }}
    if(evt.getSource() == load){try {
                cur_canvas.loadFile();
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        }}
    if(evt.getSource() == connect_to_user) {
    	int con = userList.getSelectedIndex();
        String newHost = onlineUsers.get(con);
        addNewUser(newHost, "8888");
        if(NamesAndPorts.size() == 1 ) {
        	getAllDrawings();
        }
        new ReciprocalConnectionThread(newHost, 8888, ThisComputerHostName).start();
    }
}
 
public void printUniqueNames() {
        for(int i = 0; i < UniqueTabNames.size(); i++) {
                System.out.println(UniqueTabNames.get(i));
        }
}
 
public void mousePressed(MouseEvent e) {
           cur_canvas.drawCircle(e.getPoint());
           cur_canvas.setCurPoint(e.getPoint());               
}
 
@Override
public void mouseClicked(MouseEvent e) {
           cur_canvas.drawCircle(e.getPoint());
           cur_canvas.setCurPoint(e.getPoint());
}
 
@Override
public void mouseEntered(MouseEvent arg0) {
        // TODO Auto-generated method stub     
}
 
@Override
public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub     
}
 
@Override
public void mouseReleased(MouseEvent arg0) {
    cur_canvas.resetFirst();
    System.out.println("released");
    System.out.println("The length of the array of changes that are sent is :   " + PointsToBeSent.size());
    sendPointsToOtherUsers();
}
 
@Override
public void mouseDragged(MouseEvent e) {       
          cur_canvas.drawCircle(e.getPoint());
          cur_canvas.setCurPoint(e.getPoint());
}

@Override
public void mouseMoved(MouseEvent arg0) {
        // TODO Auto-generated method stub     
}
 
public void addAPointToBeSent( PointDrawn newPoint ) {
        PointsToBeSent.add(newPoint);
}
 
public void sendPointsToOtherUsers() {
        String UniqueStringofTabToBeChanged = UniqueTabNames.get(tabbedPane.getSelectedIndex());
         for(int i = 0; i < NamesAndPorts.size(); i++) {
                        SocketThreadForArrayOfChanges CurSend = new SocketThreadForArrayOfChanges(NamesAndPorts.get(i).HostName, NamesAndPorts.get(i).PortNumber, UniqueStringofTabToBeChanged, PointsToBeSent);
                        CurSend.start();
         }
         PointsToBeSent = new Vector<PointDrawn>();
}

public int getSelectedTab() {
        return tabbedPane.getSelectedIndex();
        //then got to get the unique string name associated with this tab index
}
 
public void addPoints(Vector<PointDrawn> newPoints, String TabToAddTo) {
        System.out.println("This is in add points   " + TabToAddTo);
        System.out.println("There are   " + tabbedPane.getTabCount() + "  tabbed panes");
        System.out.println("UTP size is   " + UniqueTabNames.size());
       
        int IndexOfTab = UniqueTabNames.indexOf(TabToAddTo);
        if(IndexOfTab != -1){
                ((PaintCanvas)tabbedPane.getComponentAt(IndexOfTab)).addPoints(newPoints);             
        }
}
 
public void addNewUser(String NewHostName, String NewPortNumber) {
        int IntPortNumber = Integer.parseInt(NewPortNumber);
        for(int i = 0; i < NamesAndPorts.size(); i++) {
            String Host = NamesAndPorts.get(i).getHostName();
            if(Host.equalsIgnoreCase(NewHostName)) return;
        }
        NamesAndPorts.add(new HostNameAndPortNumber(NewHostName, IntPortNumber));
}
 
public void addFirstTab() {
      String UniqueName = new Date().toString();
      PaintCanvas newCanvas = new PaintCanvas(this);
      newCanvas.addMouseMotionListener(this);
      tabbedPane.add("First", newCanvas);
      UniqueTabNames.add(UniqueName);
      createUserPanel();
}
 
public void addAnotherPaintingTabForAll(String Title, String UniqueName) {
        PaintCanvas newCanvas = new PaintCanvas(this);
        newCanvas.addMouseListener(this);
    newCanvas.addMouseMotionListener(this);
    tabbedPane.add(Title, newCanvas);
    UniqueTabNames.add(UniqueName);
}

public void sendAllTabs(String ForeignHost) {
        for(int i = 0; i < tabbedPane.getTabCount(); i++) {
                String UniqueTabName = UniqueTabNames.get(i);
                String TabName = tabbedPane.getTitleAt(i);
                SocketThreadForNewTab NewTab = new SocketThreadForNewTab(ForeignHost, 8888, TabName, UniqueTabName);
                NewTab.start();
        }
}

public PaintCanvas createNewTab(String uniqueName) {
	UniqueTabNames.add(uniqueName);
    PaintCanvas newCanvas = new PaintCanvas(this);
    return newCanvas;
}

public void addNewTabForPainting() {
		String uniqueName = new Date().toString();
        PaintCanvas newCanvas = createNewTab(uniqueName);
        String Title = JOptionPane.showInputDialog("Please enter a new name for your Painting project:");   
        if(Title != null) {
                newCanvas.addMouseListener(this);
            newCanvas.addMouseMotionListener(this);
            tabbedPane.add(Title, newCanvas);
            for(int i = 0; i < NamesAndPorts.size(); i++) {
                 new SocketThreadForNewTab(NamesAndPorts.get(i).HostName, NamesAndPorts.get(i).PortNumber, Title, uniqueName).start();
            }
        }
}

public void addNewTabForPaintingLoad(File selected) throws FileNotFoundException {	
	String uniqueName = new Date().toString();
	PaintCanvas newCanvas = createNewTab(uniqueName);
    String Title = selected.getName();   
    if(Title != null) {
        newCanvas.addMouseListener(this);
        newCanvas.addMouseMotionListener(this);
        tabbedPane.add(Title, newCanvas);        
    } 
    if(selected != null) {    	
        Scanner input = new Scanner(selected);  
        while(input.hasNext()) {        	
                String CurLine = input.next();
                String[] CurPointAttributes = CurLine.split(":");
                int x = Integer.parseInt(CurPointAttributes[0]);
                int y = Integer.parseInt(CurPointAttributes[1]);
                int radius = Integer.parseInt(CurPointAttributes[2]);
                int ColorRGB = Integer.parseInt(CurPointAttributes[3]);                         
                newCanvas.circle_list.add(new PointDrawn(x, y, radius, new Color(ColorRGB), 1 == Integer.parseInt(CurPointAttributes[4])));                
        }
        
        for(int i = 0; i < NamesAndPorts.size(); i++) {
        	String hostName = NamesAndPorts.get(i).getHostName();
            SocketThreadForWholeDrawing drawingSocket = new SocketThreadForWholeDrawing(hostName, 8888, uniqueName, Title, newCanvas.getCircles());
            drawingSocket.start();
        }
    }    
}
 
public void getCurTab(){
        cur_canvas = new PaintCanvas(this);
        curTab = tabbedPane.getSelectedIndex();
        cur_canvas = (PaintCanvas) tabbedPane.getComponentAt(curTab);
}

@Override
public void stateChanged(ChangeEvent e) {
        if(e.getSource() == tabbedPane){
                getCurTab();
                setSizeColorButton();
        }
}
public void setSizeColorButton(){
        size_col.setBackground(cur_canvas.line_color);
        size_col.setText(Integer.toString(cur_canvas.pen_radius));
}

public void deleteUser(String leavingUsersHostName) {
	for(int i = 0; i < NamesAndPorts.size(); i++) {
        HostNameAndPortNumber CurHostAndPort = NamesAndPorts.get(i);
        String CurHostName = CurHostAndPort.getHostName();
		if(CurHostName.equalsIgnoreCase(leavingUsersHostName)) {
			NamesAndPorts.remove(i);
		}
   }
}

public void sendAllDrawings(String hostName){
        SocketThreadForWholeDrawing drawingSocket;
        PaintCanvas canvas;
        for(int i = 0; i < UniqueTabNames.size(); i++){
                canvas = (PaintCanvas)tabbedPane.getComponentAt(i);
                drawingSocket = new SocketThreadForWholeDrawing(hostName, 8888, UniqueTabNames.get(i), tabbedPane.getTitleAt(i), canvas.getCircles());
                drawingSocket.start();
        }
}

public void getAllDrawings(){
        if( NamesAndPorts.size() >=1 ) {
                SocketThreadForAllDrawingsRequest socket = new SocketThreadForAllDrawingsRequest(NamesAndPorts.get(0));
                socket.start();
        }
}

public boolean tabPresent(String uniqueTabName){
        int index = UniqueTabNames.indexOf(uniqueTabName);
        if(index == -1)return false;
        else return true;
}
}